package cn.elead.it.sso.server.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.gitee.elead.web.controller.SuperController;

import cn.elead.it.sso.core.constant.GlobalVariable;
import cn.elead.it.sso.core.login.SsoWebLoginHelper;
import cn.elead.it.sso.core.model.SsoUser;
import cn.elead.it.sso.core.store.SsoLoginStore;
import cn.elead.it.sso.core.store.SsoSessionIdHelper;
import cn.elead.it.sso.core.util.RSAUtil;
import cn.elead.it.sso.server.oauth.param.OauthFormLoginParam;
import cn.elead.it.sso.system.emuns.UserStatusEnum;
import cn.elead.it.sso.system.model.Client;
import cn.elead.it.sso.system.model.User;
import cn.elead.it.sso.system.service.IClientService;
import cn.elead.it.sso.system.service.IUserService;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;

/**
 * web模式登录控制器
 * 
 * @author luopeng
 *
 */
@Controller
public class WebController extends SuperController {

	@Value("${ras.privateKey}")
	private String privateKey;
	
	@Autowired
	private IUserService userService;

	@Autowired
	private IClientService clientService;

	@RequestMapping("/")
	public String index(Model model, HttpServletRequest request, HttpServletResponse response) {

		// 校验当前是否已经登录
		SsoUser ssoUser = SsoWebLoginHelper.loginCheck(request, response);
		if (ObjectUtil.isNull(ssoUser)) {
			// 没有登录重定向到登录页面
			return GlobalVariable.REDIRECT_URI_PREFIX + GlobalVariable.SSO_LOGIN;
		} else {
			String redirectUrl = request.getParameter(GlobalVariable.REDIRECT_URI);
			if (redirectUrl != null && redirectUrl.trim().length() > 0) {
				String sessionId = SsoWebLoginHelper.getSessionIdByCookie(request);
				String redirectUrlFinal = redirectUrl + "?" + GlobalVariable.SSO_SESSIONID + "=" + sessionId;
				return GlobalVariable.REDIRECT_URI_PREFIX + redirectUrlFinal;
			} else {
				return GlobalVariable.REDIRECT_URI_PREFIX + "/";
			}
		}
	}

	/**
	 * Login page
	 *
	 * @param model
	 * @param request
	 * @return
	 */
	@GetMapping(GlobalVariable.SSO_LOGIN)
	public String login(Model model, HttpServletRequest request, HttpServletResponse response) {

		// 获取客户端信息
		String clientId = request.getParameter(GlobalVariable.CLIENT_ID);
		Client client = clientService.findByClientId(clientId);
		if (ObjectUtil.isNull(client)) {
			// 进入错误页面
			model.addAttribute("errorMsg", "您好,请先注册单点客户端信息！");
			return GlobalVariable.DEFAULT_ERROR_PAGE_PATH;
		}

		// login check
		SsoUser ssoUser = SsoWebLoginHelper.loginCheck(request, response);
		if (ssoUser != null) {
			// success redirect
			String redirectUrl = request.getParameter(GlobalVariable.REDIRECT_URI);
			if (redirectUrl != null && redirectUrl.trim().length() > 0) {
				String sessionId = SsoWebLoginHelper.getSessionIdByCookie(request);
				String redirectUrlFinal = redirectUrl + "?" + GlobalVariable.SSO_SESSIONID + "=" + sessionId;
				return GlobalVariable.REDIRECT_URI_PREFIX + redirectUrlFinal;
			} else {
				return GlobalVariable.REDIRECT_URI_PREFIX + "/";
			}
		}

		// 进入登录页面
		model.addAttribute("errorMsg", request.getParameter("errorMsg"));
		model.addAttribute(GlobalVariable.REDIRECT_URI, request.getParameter(GlobalVariable.REDIRECT_URI));
		model.addAttribute(GlobalVariable.DEFAULT_LOGIN_PAGE_CLIENT_INFO_KEY, client);
		return GlobalVariable.THEME + GlobalVariable.DEFAULT_LOGIN_PAGE_PATH;
	}

	/**
	 * Login
	 *
	 * @param request
	 * @param redirectAttributes
	 * @param username
	 * @param password
	 * @return
	 * @throws Exception 
	 */
	@PostMapping(GlobalVariable.SSO_LOGIN)
	public String doLogin(RedirectAttributes redirectAttributes, OauthFormLoginParam oauthFormLoginParam) throws Exception {

		// 获取客户端信息
		Client client = clientService.findByClientId(oauthFormLoginParam.getClientId());
		if (ObjectUtil.isNull(client)) {
			// 进入错误页面
			redirectAttributes.addAttribute("errorMsg", "您好,请先注册单点客户端信息！");
			return GlobalVariable.DEFAULT_ERROR_PAGE_PATH;
		}

		String username = oauthFormLoginParam.getUsername();
		String password = oauthFormLoginParam.getPassword();

		// valid login
		User user = userService.findUser(username);
		if (ObjectUtil.isNull(user)) {
			return redirectLogin(redirectAttributes, client, "用户不存在");
		}
		
		password = RSAUtil.encryptByPrivateKey(password, privateKey);
		if (!password.equals(user.getPassword())) {
			return redirectLogin(redirectAttributes, client, "用户名密码错误");
		}
		if (UserStatusEnum.NORMAL.equals(user.getStatus())) {
			return redirectLogin(redirectAttributes, client, "用户被禁用");
		}

		// 1、make sso user
		SsoUser ssoUser = new SsoUser();
		ssoUser.setUserId(user.getUserId());
		ssoUser.setUserName(user.getUserName());
		ssoUser.setVersion(IdUtil.simpleUUID());
		ssoUser.setExpireMinite(SsoLoginStore.getRedisExpireMinite());
		ssoUser.setExpireFreshTime(System.currentTimeMillis());
		ssoUser.setClientSecret(client.getClientSecret());

		// 2、make session id
		String sessionId = SsoSessionIdHelper.makeSessionId(ssoUser);

		// 3、login, store storeKey + cookie sessionId
		SsoWebLoginHelper.login(response, sessionId, ssoUser, oauthFormLoginParam.isIfRemember());

		// 4、return, redirect sessionId
		String redirectUrl = request.getParameter(GlobalVariable.REDIRECT_URI);
		if (redirectUrl != null && redirectUrl.trim().length() > 0) {
			String redirectUrlFinal = redirectUrl + "?" + GlobalVariable.SSO_SESSIONID + "=" + sessionId;
			return GlobalVariable.REDIRECT_URI_PREFIX + redirectUrlFinal;
		} else {
			return GlobalVariable.REDIRECT_URI_PREFIX + "/";
		}

	}

	/**
	 * Logout
	 *
	 * @param request
	 * @param redirectAttributes
	 * @return
	 */
	@RequestMapping(GlobalVariable.SSO_LOGOUT)
	public String logout(HttpServletRequest request, HttpServletResponse response,
			RedirectAttributes redirectAttributes) {

		// logout
		SsoWebLoginHelper.logout(request, response);

		redirectAttributes.addAttribute(GlobalVariable.REDIRECT_URI, request.getParameter(GlobalVariable.REDIRECT_URI));
		redirectAttributes.addAttribute(GlobalVariable.CLIENT_ID, request.getParameter(GlobalVariable.CLIENT_ID));
		return GlobalVariable.REDIRECT_URI_PREFIX + GlobalVariable.SSO_LOGIN;
		// return GlobalVariable.DEFAULT_ERROR_PAGE_PATH;
	}

	/**
	 * 重定向到登录页面
	 * 
	 * @param redirectAttributes
	 * @param client
	 * @param errorMsg
	 * @return
	 */
	private String redirectLogin(RedirectAttributes redirectAttributes, Client client, String errorMsg) {
		redirectAttributes.addAttribute("client_id", client.getClientId());
		redirectAttributes.addAttribute("errorMsg", errorMsg);
		redirectAttributes.addAttribute(GlobalVariable.REDIRECT_URI, request.getParameter(GlobalVariable.REDIRECT_URI));
		return GlobalVariable.REDIRECT_URI_PREFIX + GlobalVariable.SSO_LOGIN;
	}

}